package pl.prv.polanie.client.widgets;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import pl.prv.polanie.client.Planner;
import pl.prv.polanie.client.dto.ICSDTO;
import pl.prv.polanie.client.dto.ICSVDTO;

import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.Composite;


public class SelectBoxWithObjects extends Composite {

	private SelectBox listBox = new SelectBox();
	
	/** list of Object objects*/
	private List objects = new ArrayList();
	
	public SelectBoxWithObjects() {
		initWidget(listBox);
	}
	
	
	public void setVisibleItemsCount(int visibleItems) {
		listBox.setVisibleItemsCount(visibleItems);
	}

	public int getVisibleItemsCount() {
		return listBox.getVisibleItemsCount();
	}

	public void addItem(String item, Object object) {
		listBox.addItem(item);
		objects.add(object);
	}
	
	
	
	public void setHeightToDisplayItemsCount(int visibleItems) {
		listBox.setHeightToDisplayItemsCount(visibleItems);
	}


	public void removeObjectWithID(long id) {
		int indexOfObjectWithID = getIndexOfObjectWithGivenID(id);
		
		int selectedObjectIndex = getSelectedIndex();
		
		if (indexOfObjectWithID != -1) {
			Planner.log("SelectBoxWithObjects.removeObjectWithID: " + "usuwam obiekt z SB o id " + id);
			listBox.removeItem(indexOfObjectWithID);
			objects.remove(indexOfObjectWithID);


			
			//USUNIETO WYBRANY OBIEKT -> trzeba wybrac inny
			if (indexOfObjectWithID == selectedObjectIndex) {
				if (getItemCount() == 0) {
					clear();
				} else {
					setSelectedIndex(0);
				}
			}
		}
	}

	/**
	 * Sprwadza, czy do kontrolki zostal dodany juz obiekt o podanym id. Jesli tak, zostaje on updateowany.
	 * @param item
	 * @param object
	 */
	public void addItemOrUpdate(String item, Object object) {
		listBox.addItem(item);
		objects.add(object);
	}

	
	public void addChangeListener(ChangeListener listener) {
		listBox.addChangeListener(listener);
	}


	public void clear() {
		listBox.clear();
		objects.clear();
	}


	public int getItemCount() {
		return listBox.getItemCount();
	}


	public String getItemText(int index) {
		return listBox.getItemText(index);
	}


	public int getSelectedIndex() {
		return listBox.getSelectedIndex();
	}


	public String getValue(int index) {
		return listBox.getValue(index);
	}


	public void setSelectedIndex(int index) {
		listBox.setSelectedIndex(index);
	};
	
	public Object getObject(int index) {
		return objects.get(index);
	}
	
	public Object getSelectedObject() {
		return objects.get(listBox.getSelectedIndex());
	}

	public void setItemsPanelWidth(int width) {
		listBox.setItemsPanelWidth(width);
	}
	
	/**
	 * Przeglada wszystkie dodane obiekty i jesli ktorys z nich bedzie implementacja ICSDTO
	 * i jego id bedzie rowne podanemu, to zaznaczy ten rekord.
	 * @param id
	 */	
	public void setSelectedObjectWithID(long id) {
		Planner.log("SelectBoxWithObjects.setSelectedObjectWithID: zaznaczam obiekt o id " + id);
		
		int index = -1;
		index = getIndexOfObjectWithGivenID(id);
		
		if (index != -1) {
			setSelectedIndex(index);
		}
	}


	/**
	 * @param id
	 */
	private int getIndexOfObjectWithGivenID(long id) {
		for (int i = 0; i < objects.size(); i++) {
			Object o = objects.get(i);
			if (o instanceof ICSDTO) {
				ICSDTO csDTO = (ICSDTO) o;
				if (csDTO.getId() == id) {
					Planner
							.log("SelectBoxWithObjects.getIndexOfObjectWithGivenID: "
									+ "ZWRACAM " + i);
					return i;
				}
			}
		}
		Planner
		.log("SelectBoxWithObjects.getIndexOfObjectWithGivenID: "
				+ "ZWRACAM " + (-1));
		
		return -1;
	}
	

	
	@Override
	public void setWidth(String width) {
//		super.setWidth(width);
		listBox.setWidth(width);
	}
	
	
	/**
	 * Sorts elements in SelectBox based on labels.
	 */
	public void sortWithAlphabeticalOrder() {
		Object selectedObject = getSelectedObject();
//		int selectedIndex = getSelectedIndex();
		
		//towrzymy liste z elementami
		List<StringKeyWithObject> list = new ArrayList<StringKeyWithObject>();
		
		for (int i = 0; i < getItemCount(); i++) {
			StringKeyWithObject skwo = new StringKeyWithObject(listBox.getItemText(i), objects.get(i));
			list.add(skwo);
		}
		
		Collections.sort(list);
		
		//czyscimy liste
		clear();
		
		
		for (int i = 0; i < list.size(); i++) {
			StringKeyWithObject skwo = list.get(i);
			addItem(skwo.getLabel(), skwo.getObject());
			
			//przepisanie zaznaczenia obiektu
			if (skwo.getObject().equals(selectedObject)) {
				setSelectedIndex(i);
//				Planner.log("SelectBoxWithObjects.sortWithAlphabeticalOrder: " + "PRZEPISUJE " + i);
			}
		}
	}
	
	
	
	class StringKeyWithObject implements Comparable<StringKeyWithObject> {
		String label;
		Object object;
		
 		public StringKeyWithObject(String label, Object object) {
			this.label = label;
			this.object = object;
		}

 		public int compareTo(StringKeyWithObject o) {
 			return this.label.compareToIgnoreCase(o.label);
 		}

		public String getLabel() {
			return label;
		}

		public void setLabel(String label) {
			this.label = label;
		}

		public Object getObject() {
			return object;
		}

		public void setObject(Object object) {
			this.object = object;
		}
	}



	public boolean isEnabled() {
		return listBox.isEnabled();
	}


	public void setEnabled(boolean enabled) {
		listBox.setEnabled(enabled);
	};
	
}
